<template>
	<div class="app-container">
		<div class="wx-user-box">
			<div class="wx-user-title">权限组管理</div>
			<div class="search-box">
				<el-table :data="rolesList" style="width: 100%;" border>
					<el-table-column align="center" label="序号" width="100">
						<template slot-scope="scope">
							{{ scope.$index + 1 }}
						</template>
					</el-table-column>
					<el-table-column align="center" label="角色名称" width="300">
						<template slot-scope="scope">
							{{ scope.row.name }}
						</template>
					</el-table-column>
					<el-table-column align="header-center" label="描述">
						<template slot-scope="scope">
							{{ scope.row.des }}
						</template>
					</el-table-column>
					<el-table-column align="right" >
						<template slot="header">
							<el-button type="primary" @click="handleAddRole" icon="el-icon-circle-plus-outline">{{ $t('permission.addRole') }}</el-button>
						</template>
						<template slot-scope="scope">
							<el-button  size="small" v-if="scope.row.id !== -1" @click="handleEdit(scope)" icon="el-icon-edit">编辑权限</el-button>
							<el-button type="danger" size="small" v-if="scope.row.id !== -1" @click="handleDelete(scope)" icon="el-icon-delete">删除</el-button>
						</template>
					</el-table-column>
				</el-table>

				<el-dialog :visible.sync="dialogVisible" :title="dialogType === 'edit' ? '修改' : '添加'" top="30px">
					<el-form :model="role" label-width="80px" label-position="left">
						<el-form-item label="名称"><el-input v-model="role.name" placeholder="请输入角色名称" /></el-form-item>
						<el-form-item label="描述">
							<el-input v-model="role.des" :autosize="{ minRows: 2, maxRows: 4 }" type="textarea" placeholder="请输入角色描述" />
						</el-form-item>
						<el-form-item label="Menus">
							<el-tree
								style="height: calc(100vh - 400px);overflow-y: auto;"
								ref="tree"
								:check-strictly="checkStrictly"
								default-expand-all
								:data="routesData"
								:props="defaultProps"
								show-checkbox
								node-key="id"
								class="permission-tree"
							/>
						</el-form-item>
					</el-form>
					<div style="text-align:right;">
						<el-button type="danger" @click="dialogVisible = false">取消</el-button>
						<el-button type="primary" @click="confirmRole">确定</el-button>
					</div>
				</el-dialog>
			</div>
		</div>
	</div>
</template>

<script>
import path from 'path';
import { deepClone } from '@/utils';
import { getRoutes, getRoles, addRole, deleteRole, updateRole, saveRoleInfo, getRoleInfo, getRoleQuery, getRolesList, RoleDelete } from '@/api/role';
import i18n from '@/lang';

const defaultRole = {
	key: '',
	name: '',
	des: '',
	routes: []
};

export default {
	data() {
		return {
			role: Object.assign({}, defaultRole),
			routes: [],
			rolesList: [],
			dialogVisible: false,
			dialogType: 'new',
			checkStrictly: false,
			defaultProps: {
				children: 'children',
				label: 'name'
			},
			obj:{}
		};
	},
	computed: {
		routesData() {
			return this.routes;
		}
	},
	created() {
		// Mock: get all routes and roles list from server
		// this.getRoutes()
		// this.getRoles()
		this.getData();
		this.getRoleQuery();
	},
	methods: {
		// 获取菜单列表
		async getData() {
			getRolesList({
				pageSize: 9999,
				pageNumber: 1
			}).then(res => {
				let list = res.pageData.list;
				this.routes = list;
				let obj = {};
				res.pageData.list.forEach(item => {
					obj[item.id] = item;
					if(item.children && item.children.length) {
						delete obj[item.id]
						item.children.forEach(item1 => {
							obj[item1.id] = item1;
							if(item1.children && item1.children.length) {
								delete obj[item1.id]
								item1.children.forEach(item2 => {
									obj[item2.id] = item2;
								})
							}
						})
					}
				});
				this.obj = obj;
			});
		},
		// 获取角色列表
		async getRoleQuery() {
			getRoleQuery().then(res => {
				if (res.state) {
					this.rolesList = res.data;
				}
			});
		},

		async getRoutes() {
			const res = await getRoutes();
			this.serviceRoutes = res.data;
			const routes = this.generateRoutes(res.data);
			this.routes = this.i18n(routes);
		},
		async getRoles() {
			const res = await getRoles();
			this.rolesList = res.data;
		},
		i18n(routes) {
			const app = routes.map(route => {
				route.title = i18n.t(`route.${route.title}`);
				if (route.children) {
					route.children = this.i18n(route.children);
				}
				return route;
			});
			return app;
		},
		// Reshape the routes structure so that it looks the same as the sidebar
		generateRoutes(routes, basePath = '/') {
			const res = [];

			for (let route of routes) {
				// skip some route
				if (route.hidden) {
					continue;
				}

				const onlyOneShowingChild = this.onlyOneShowingChild(route.children, route);

				if (route.children && onlyOneShowingChild && !route.alwaysShow) {
					route = onlyOneShowingChild;
				}

				const data = {
					path: path.resolve(basePath, route.path),
					title: route.meta && route.meta.title
				};

				// recursive child routes
				if (route.children) {
					data.children = this.generateRoutes(route.children, data.path);
				}
				res.push(data);
			}
			return res;
		},
		generateArr(routes) {
			let data = [];
			routes.forEach(route => {
				data.push(route);
				if (route.children) {
					const temp = this.generateArr(route.children);
					if (temp.length > 0) {
						data = [...data, ...temp];
					}
				}
			});
			return data;
		},
		handleAddRole() {
			this.role = Object.assign({}, defaultRole);
			if (this.$refs.tree) {
				this.$refs.tree.setCheckedNodes([]);
			}
			this.dialogType = 'new';
			this.dialogVisible = true;
		},
		handleEdit(scope) {
			this.dialogType = 'edit';
			this.dialogVisible = true;
			this.role = deepClone(scope.row);
			let routeIdList = [];
			this.role.roleRes.forEach(item => {
				if (item.checked && this.obj[item.id]) {
					routeIdList.push({ id: item.id });
				}
			});

			this.$nextTick(() => {
				const routes = routeIdList;
				this.$refs.tree.setCheckedNodes(routes);
			});
		},
		handleDelete({ $index, row }) {
			this.$confirm('确认删除该角色吗?', '提示', {
				confirmButtonText: '确认',
				cancelButtonText: '取消',
				type: 'warning'
			})
				.then(async () => {
					await RoleDelete({ id: row.id }).then(res => {
						if (res.state) {
							this.rolesList.splice($index, 1);
							this.$message({
								type: 'success',
								message: '删除成功！'
							});
						} else {
							this.$message.error('删除失败！');
						}
					});
				})
				.catch(err => {
					console.error(err);
				});
		},
		generateTree(routes, basePath = '/', checkedKeys) {
			const res = [];

			for (const route of routes) {
				const routePath = path.resolve(basePath, route.path);

				// recursive child routes
				if (route.children) {
					route.children = this.generateTree(route.children, routePath, checkedKeys);
				}

				if (checkedKeys.includes(routePath) || (route.children && route.children.length >= 1)) {
					res.push(route);
				}
			}
			return res;
		},
		async confirmRole() {
			if (!this.role.name) {
				this.$message.error('请输入角色名称');
				return;
			}
			if (!this.role.des) {
				this.$message.error('请输入角色描述');
				return;
			}
			const checkedKeys = this.$refs.tree.getCheckedKeys();
			const checkedKeysarr = this.$refs.tree.getCheckedNodes();
			checkedKeysarr.forEach(res => {
				if (res.pid) {
					checkedKeys.push(res.pid);
				}
			});
			// 去重
			let Keys = this.unique(checkedKeys);
			if (Keys.length === 0) {
				this.$message.error('权限不能为空');
				return;
			}
			const isEdit = this.dialogType === 'edit';

			// this.role.routes = this.generateTree(deepClone(this.serviceRoutes), '/', checkedKeys)

			if (isEdit) {
				let data = {};
				data['role.id'] = this.role.id;
				data['role.name'] = this.role.name; //名称
				data['role.role_code'] = ''; //代码
				data['role.des'] = this.role.des; //描述
				data['roilelist'] = Keys.join(); //菜单id逗号分隔

				saveRoleInfo(data).then(res => {
					if (res.state) {
						this.getRoleQuery();
					}
				});
			} else {
				let data = {};
				data['role.name'] = this.role.name; //名称
				data['role.role_code'] = ''; //代码
				data['role.des'] = this.role.des; //描述
				data['roilelist'] = Keys.join(); //菜单id逗号分隔

				saveRoleInfo(data).then(res => {
					if (res.state) {
						this.getRoleQuery();
					}
				});
			}

			const { des, key, name } = this.role;
			this.dialogVisible = false;
			this.$notify({
				title: '成功',
				dangerouslyUseHTMLString: true,
				message: `
            <div>角色名称: ${name}</div>
            <div>角色描述: ${des}</div>
          `,
				type: 'success'
			});
		},
		// reference: src/view/layout/components/Sidebar/SidebarItem.vue
		onlyOneShowingChild(children = [], parent) {
			let onlyOneChild = null;
			const showingChildren = children.filter(item => !item.hidden);

			// When there is only one child route, the child route is displayed by default
			if (showingChildren.length === 1) {
				onlyOneChild = showingChildren[0];
				onlyOneChild.path = path.resolve(parent.path, onlyOneChild.path);
				return onlyOneChild;
			}

			// Show parent if there are no child route to display
			if (showingChildren.length === 0) {
				onlyOneChild = { ...parent, path: '', noShowingChildren: true };
				return onlyOneChild;
			}

			return false;
		},
		// 去重
		unique(arr) {
			if (!Array.isArray(arr)) {
				console.log('type error!');
				return;
			}
			arr = arr.sort();
			var arrry = [arr[0]];
			for (var i = 1; i < arr.length; i++) {
				if (arr[i] !== arr[i - 1]) {
					arrry.push(arr[i]);
				}
			}
			return arrry;
		}
	}
};
</script>

<style lang="scss" scoped>
.app-container {
	.roles-table {
		margin-top: 30px;
	}
	.permission-tree {
		margin-bottom: 30px;
	}
}
</style>
